//
//                 Configuration and main()
//
#include <stdio.h>
#include <cmn\userLib.h>
#include <cmn\picConfig.h>
#include <a2d\a2d.h>
#include <pwm\pwm.h>
#include <pwm\vexMotor.h>
#include <cmn\flash.h>
#include <rfinder\rfinder_TS601P01.h>
#include <lib_usb_cdc.h>
#include "my_main.h"

// externs for PWM and Vex motor handles returned by open

extern UINT16 pwm1Handle;
extern UINT16 pwm2Handle;
extern UINT16 pwm3Handle;
extern UINT16 pwm4Handle;
extern UINT16 pwm5Handle;
extern UINT16 vex1Handle;
extern UINT16 vex2Handle;
extern UINT16 vex3Handle;
extern UINT16 vex4Handle;
extern UINT16 vex5Handle;
extern UINT16 max541Handle;

#ifdef USE_LEDS

// led pin assignments

#if (__PIC32_FEATURE_SET__ >= 300)

#define	TRIS_LEDS_ALL TRISE		led pin bank assignment 
#define	LAT_LEDS_ALL  LATE		led pin bank assignment 

#else

#define	TRIS_LED0 _TRISA4		
#define	LAT_LED0 _LATA4			

#define	TRIS_LED1 _TRISB4		
#define	LAT_LED1 _LATB4			

#define	TRIS_LED2 _TRISB2		
#define	LAT_LED2 _LATB2			

#define	TRIS_LED3 _TRISB3		
#define	LAT_LED3 _LATB3			
 
#endif
#endif

// chceks param and if not 0, displays in LEDs and hangs

void checkrc(int rc)
{	
	if(!rc) 
		return;
#if (__PIC32_FEATURE_SET__ >= 300)
	ledOut(rc & 0xFF);			// configures LEDs to use LATE pins
#else
	ledOut(rc & 0x1F);			// uses custom configured LEDs
#endif
	while(1)
	{}
}

// configures a limited set of LEDs for output to non-consecutive pins for ordered display

void ledOut( UINT16 value )
{
#ifdef USE_LEDS
#if (__PIC32_FEATURE_SET__ >= 300)

	LAT_LEDS_ALL = value; 

#else

	if((value & 8) > 0)
		LAT_LED3 = 1;
	else LAT_LED3 = 0;

	if((value & 4) > 0)
		LAT_LED2 = 1;
	else LAT_LED2 = 0;
		
	if((value & 2) > 0)
		LAT_LED1 = 1;
	else LAT_LED1 = 0;		

	if((value & 1) > 0)
		LAT_LED0 = 1;
	else LAT_LED0 = 0;
#endif
#endif
}	

INT16 initialize()      // establish PBCLK, init timer / peripheral devices
{
   INT16	rc;

   picInit(SYSCLK);          

   DDPCONbits.JTAGEN = 0;   // this will disable JTAG port to enable reassignment of those pins

#if (__PIC32_FEATURE_SET__ >= 300)
#else
	PIC32MX250_setup_pins();	// assign pins for reassignable device
#endif

#ifdef USE_LEDS

	// setup io ports to control led pin bank for debugging purposes

#if (__PIC32_FEATURE_SET__ >= 300)

	TRIS_LEDS_ALL = 0;
	LAT_LEDS_ALL = 0;
	
#else

	TRIS_LED3 = 0;
	LAT_LED3 = 0;
	TRIS_LED2 = 0;
	LAT_LED2 = 0;
	TRIS_LED1 = 0;
	LAT_LED1 = 0;
	TRIS_LED0 = 0;
	LAT_LED0 = 0;

#endif
#endif

   // select the desired timer options 
   
   // timers for delay functions

#ifdef USE_DELAY_TIMER1
	delayT1_init();      // enables use of Timer1 for delay functions
#endif
#ifdef USE_DELAY_TIMER2
	delayT2_init();      // enables use of Timer2 for delay functions
#endif
#ifdef USE_DELAY_TIMER3
	delayT3_init();      // enables use of Timer3 for delay functions
#endif
#ifdef USE_DELAY_TIMER4
	delayT4_init();      // enables use of Timer4 for delay functions
#endif
#ifdef USE_DELAY_TIMER5
	delayT5_init();      // enables use of Timer5 for delay functions
#endif

	// timers for timeElapsed functions
	
#ifdef USE_COMBINED_TIMER23
//	OpenTimer23(T2_ON | T2_SOURCE_INT | T23_PRESCALER | T2_32BIT_MODE_ON, 0xFFFFFFFF);
#endif
#ifdef USE_COMBINED_TIMER45
//	OpenTimer45(T4_ON | T4_SOURCE_INT | T45_PRESCALER | T4_32BIT_MODE_ON, 0xFFFFFFFF);
#endif

	// UART device selection
	// Param1 = port #: UART1A, UART2A, UART3A, etc
	// Param2 = data rate (bps) data
	// Param3 = PBCLK

#ifdef USE_UART
#if (__PIC32_FEATURE_SET__ >= 300)
/*	
	_TRISF5 = 0;						// set UART3A TX pin as output
	_TRISF12 = 1;						// set RX pin as input
	uart_init(UART3A, 230400, PBCLK);
*/

	_TRISB14 = 0;						// set UART3B TX pin as output
	_TRISB8 = 1;						// set RX pin as input
	uart_init(UART3B, 230400, PBCLK);

#else
	_TRISB14 = 0;						// set UART2 TX pin as output
	_TRISB8 = 1;						// set RX pin as input
	uart_init(UART2, 115200, PBCLK);
#endif
#endif

	//setbuf() specifies no stdout buffering: all chars output immediately

	setbuf(stdout,NULL);            // specify no buffering on output
  
   // usb 

#ifdef USE_USB

   	lib_usb_cdc_open();				// usb open

#endif

   // I2C devices
   
#ifdef USE_I2C

// to be added 

#endif

#ifdef USE_MAX541

// MAXIM 541 D/A chip

	max541Handle = MAX541Open(  SPI_CHANNEL1A,	// PIC32MX SPI 1A
								10000000,		// 10MHz SPI Clk
					 			IOPORT_D,		// Chip Sel Pin Port D
					 			BIT_5,			// Chip Sel Pin Bit 5
					 			PBCLK );		// Periph Bus Clk
	if(max541Handle == -1)
		return(-1);

#endif

// PWM

#ifdef USE_PWM

	pwm1Handle = PWMOpen( 1, 2, T2_PS_1_32, 0xC000 );		// PWM open port OC1, Timer 2
	if(pwm1Handle == -1)
		return(-1);

#endif

// Vex Motor

	vex1Handle = VexMotorOpen( VEX_MOTOR1, 2 );	// see mymain.h for which OCx device, timer 2
	if( vex1Handle == -1 )
		return(-1);

	rc = VexMotorWrite( vex1Handle, 0 );	// begin with motor stopped
	checkrc(rc);
	
	vex2Handle = VexMotorOpen( VEX_MOTOR2, 2 );	// see mymain.h for which OCx device, timer 2
	if( vex2Handle == -1 )
		return(-1);
	rc = VexMotorWrite( vex2Handle, 0 );// begin with motor stopped
	checkrc(rc);

// analog to digital inputs

#ifdef A2D_MASK
	A2D_init(A2D_MASK);				// parm = ANx bits to enable as inputs
#endif

	return(0);
}

main()
{
	int	rc;							// return code
	
	// configure / open devices
	
	rc = initialize();
	checkrc(rc);
	
	// invoke application code
	
	my_main();
}	